package sqlstore

import (
	"fmt"
	"sync"
	"errors"
	"database/sql"

	"github.com/astaxie/beego"
	"gopkg.in/jetgeng/mergo.v1"

	"yikexing.com.cn/wyws/models"
	"yikexing.com.cn/wyws/bus"
)

func init() {
	bus.AddHandler("sql", AddDict)
	bus.AddHandler("sql", UpdateDict)
	bus.AddHandler("sql", GetDict)
	bus.AddHandler("sql", DeleteDict)
	bus.AddHandler("sql", GetDictDetail)

}

func AddDict(addDict *models.AddDict) error {
	detailCmd := models.GetDictDetail{}
	cmd := addDict.DictCommand
	dict := models.Dict{
		Value:cmd.Value,
		Label:cmd.Label,
		DictType:cmd.DictType,
		Description:cmd.Description,
		Sort:cmd.Sort,
		Validity:true,
		CreatedUserName:"admin",
		LastUpdatedUser:"admin",
	}

	callback := func(tx *ThtfTx) error{
		rows, err := tx.NamedQuery(
			`INSERT INTO public.dict (id,
			        value, label, dict_type, description, sort, created_user_name,
			        last_updated_user, validity, date_created, last_updated)
			       VALUES(DEFAULT,
			        :value, :label, :dict_type, :description, :sort, :created_user_name,
			        :last_updated_user, :validity, now(), now())
			    RETURNING id;`, dict)
		if err != nil {
			beego.Debug(fmt.Sprintf("插入字典失败:%s", err))
			return errors.New(fmt.Sprintf("插入字典失败:%s", err))
		}
		defer rows.Close()
		for rows.Next() {
			err = rows.Scan(&dict.Id)
		}
		if err != nil {
			beego.Debug(fmt.Sprintf("映射插入的字典失败:%s", err))
			return errors.New(fmt.Sprintf("映射插入的字典失败:%s", err))
		}
		detailCmd = models.GetDictDetail{Id: int(dict.Id)}
		tx.events = append(tx.events, &detailCmd)
		return nil
	}
	er := InTransaction(callback)
	if  er != nil {
		return er
	}
	addDict.DictResults = detailCmd.Result
	return nil
}

func GetDictDetail(query *models.GetDictDetail) error{
	currentDB, err := GetDB(GetActiveDbName())
	sqlStr := `SELECT * FROM dict WHERE id = $1`
	dicts := []models.Dict{}
	dict := models.Dict{}
	err = currentDB.QueryRowx(sqlStr, query.Id).StructScan(&dict)
	if err != nil && err != sql.ErrNoRows {
		beego.Debug(fmt.Sprintf("映射插入的字典信息失败:%s", err))
		return errors.New(fmt.Sprintf("映射插入的字典信息失败:%s", err))
	}
	total := 0
	if err != sql.ErrNoRows {
		total = 1
		dicts = append(dicts, dict)
	}
	query.Result = models.DictResults{
		Result: dicts,
		Total: total,
	}
	return nil
}


//查询 字典
func GetDict(query *models.GetAllDict) error {

	currentDB, err := GetDB(GetActiveDbName())
	countSql := `from dict where validity = true`
	sqlStr := `SELECT * FROM dict where validity = true `
	if len(query.DictType) > 0 {
		countSql = fmt.Sprintf("%s and dict_type = :dict_type", countSql)
		sqlStr = fmt.Sprintf("%s and dict_type = :dict_type", sqlStr)
	}

	// 检索的总条数
	countSql = fmt.Sprintf("select count(*) count %s", countSql)
	var count int
	countResult, err := currentDB.NamedQuery(countSql, query)
	if err != nil {
		beego.Debug(fmt.Sprintf("查询备品备件信息数目失败:%s", err))
		return errors.New(fmt.Sprintf("查询备品备件信息数目失败:%s", err))
	}
	defer countResult.Close()
	countResult.Next()
	countResult.Scan(&count)
	query.DictResults.Total = count

	// 检索结果
	querySql := fmt.Sprintf("%s offset :offset limit :max", sqlStr)
	rows, err := currentDB.NamedQuery(querySql, query)
	if err != nil {
		beego.Debug(fmt.Sprintf("查询备品备件信息失败:%s", err))
		return errors.New(fmt.Sprintf("查询备品备件信息失败:%s", err))
	}
	defer rows.Close()

	for rows.Next() {
		dict := models.Dict{}
		err = rows.StructScan(&dict)
		if err != nil {
			beego.Debug(fmt.Sprintf("映射插入的备品备件信息失败:%s", err))
			return errors.New(fmt.Sprintf("映射插入的备品备件信息失败:%s", err))
		}
		query.DictResults.Result = append(query.DictResults.Result, dict)
	}
	return nil
}



var mutex sync.Mutex

func UpdateDict(updateDict *models.UpdateDict) error {
	mutex.Lock()
	defer mutex.Unlock()

	detailCmd := models.GetDictDetail{Id:updateDict.Id}
	currentDB, err := GetDB(GetActiveDbName())
	sqlStr := `select * from dict where id = $1`
	oldCmd := models.UpdateDict{}
	err = currentDB.QueryRowx(sqlStr, updateDict.Id).StructScan(&oldCmd)
	if err != nil && err != sql.ErrNoRows {
		beego.Debug(fmt.Sprintf("映射的字典信息失败:%s", err))
		return errors.New(fmt.Sprintf("映射的字典信息失败:%s", err))
	}
	validity := updateDict.Validity
	err = mergo.Merge(updateDict, oldCmd)
	if err != nil {
		beego.Debug(fmt.Sprintf("请求参数merge失败:%s", err))
		return errors.New(fmt.Sprintf("请求参数merge失败:%s", err))
	}
	updateDict.Validity = validity
	beego.Debug(updateDict)
	callback := func(tx *ThtfTx) error{
		_, err := tx.NamedExec(
			`UPDATE public.dict
			    SET value = :value, label = :label, dict_type = dict_type , description = description,
			    sort = :sort , validity = :validity, last_updated_user = :last_updated_user, last_updated = now()
			    WHERE id = :id;`, updateDict)
		if err != nil {
			beego.Debug(fmt.Sprintf("备品备件更新失败:%s", err))
			return errors.New(fmt.Sprintf("备品备件更新失败:%s", err))
		}
		tx.events = append(tx.events, &detailCmd)
		return nil
	}
	er := InTransaction(callback)
	if  er != nil {
		return er
	}
	updateDict.DictResults= detailCmd.Result
	return nil
}



func DeleteDict(delete *models.DeleteDict) error {

	gdd := models.GetDictDetail{ Id:delete.Id, }

	err := GetDictDetail(&gdd)
	if err != nil {
		return err
	}
	if gdd.Result.Total <= 0 {
		beego.Debug("没有找到数组字典")
		//没有找到备件的时候直接返回文件的id
		return errors.New(fmt.Sprintf("没有找到字典:%s", err))
	}

	uDict :=  models.UpdateDict{Id:delete.Id,Validity:false, Label:"ssssssss",
	}

	err = UpdateDict(&uDict)
	if err != nil {
		return errors.New(fmt.Sprintf("删除字典失败:%s", err))
	}

	return nil
}




